/**
 * Concrete implementation of a StackBackpack.
 * 
 * @author (Thomas KOBER) 
 * @author (Dilyan GEORGIEV)
 * 
 * @version (1.0)
 */
import java.util.*;

public class StackBackpack<E> implements MagicBackpack<E> {

	private LinkedList<E> backpack;
	
	/**
	 * Constructor for objects of class StackBackpack.
	 */
	public StackBackpack() 
	{
		super();
		
		this.backpack = new LinkedList<E>();
	}

	@Override
	/**
     * Add element to the backpack.
     * @param element to add to the end of the backpack.
     */
	public void put(E element) {
		this.backpack.push(element);
	}

	@Override
	/**
     * Take element from the backpack.
     * @return first element of the backpack and removes it from the backpack.
     * @throws NoSuchElementException if backpack is empty.
     */
	public E take() throws NoSuchElementException {
		return this.backpack.pop();
	}

	@Override
	/**
     * Returns the number of items in the backpack.
     * @return the number of items in the backpack.
     */
	public int size() {
		return this.backpack.size();
	}

	@Override
	/**
     * Checks whether or not the backpack is empty.
     * @return true if the backpack is empty, false otherwise.
     */
	public boolean isEmpty() {
		return this.backpack.isEmpty();
	}

	 @Override
	/**
     * Checks whether or not the backpack is full.
     * @return true if the backpack is full, false otherwise.
     */
    public boolean isFull() {
        return this.backpack.size() >= 5; //TODO: that needs to be dynamised!!!
    }
	
	@Override
	/**
     * Returns the first element from the backpack without removing it.
     * @return first element form the backpack.
     * @throws NoSuchElementException if the backpack is empty.
     */
	public E first() throws NoSuchElementException {
		return this.backpack.peekFirst();
	}

	@Override
	/**
     * Returns a String token representing the current type of the backpack.
     * @return a String token representing the current type of the backpack.
     */
	public String getDisplayType()
	{
	    return "(S)";
	}
	
	@Override
	/**
     * Returns a String representation of the backpack.
     * @return a String representation of the backpack.
     */
	public String toString() {
		return "[StackBackpack=" + backpack + "]";
	}

	@Override
	/**
     * Returns the hashCode of the backpack.
     * @return the hashCode of the backpack.
     */
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result
				+ ((backpack == null) ? 0 : backpack.hashCode());
		return result;
	}

	@Override
	/**
     * Checks whether or not the backpack is equal to the given object.
     * @param other object.
     * @return true if they are equal, false otherwise.
     */
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		StackBackpack other = (StackBackpack) obj;
		if (backpack == null) {
			if (other.backpack != null)
				return false;
		} else if (!backpack.equals(other.backpack))
			return false;
		return true;
	}
}